package cn.yerly.sakura.web.rest;

import com.codahale.metrics.annotation.Timed;
import cn.yerly.sakura.domain.ShopDomain;
import cn.yerly.sakura.repository.ShopDomainRepository;
import cn.yerly.sakura.repository.search.ShopDomainSearchRepository;
import cn.yerly.sakura.web.rest.util.PaginationUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.inject.Inject;
import javax.validation.Valid;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

import static org.elasticsearch.index.query.QueryBuilders.*;

/**
 * REST controller for managing ShopDomain.
 */
@RestController
@RequestMapping("/api")
public class ShopDomainResource {

    private final Logger log = LoggerFactory.getLogger(ShopDomainResource.class);

    @Inject
    private ShopDomainRepository shopDomainRepository;

    @Inject
    private ShopDomainSearchRepository shopDomainSearchRepository;

    /**
     * POST  /shopDomains -> Create a new shopDomain.
     */
    @RequestMapping(value = "/shopDomains",
            method = RequestMethod.POST,
            produces = MediaType.APPLICATION_JSON_VALUE)
    @Timed
    public ResponseEntity<Void> create(@Valid @RequestBody ShopDomain shopDomain) throws URISyntaxException {
        log.debug("REST request to save ShopDomain : {}", shopDomain);
        if (shopDomain.getId() != null) {
            return ResponseEntity.badRequest().header("Failure", "A new shopDomain cannot already have an ID").build();
        }
        shopDomainRepository.save(shopDomain);
        shopDomainSearchRepository.save(shopDomain);
        return ResponseEntity.created(new URI("/api/shopDomains/" + shopDomain.getId())).build();
    }

    /**
     * PUT  /shopDomains -> Updates an existing shopDomain.
     */
    @RequestMapping(value = "/shopDomains",
        method = RequestMethod.PUT,
        produces = MediaType.APPLICATION_JSON_VALUE)
    @Timed
    public ResponseEntity<Void> update(@Valid @RequestBody ShopDomain shopDomain) throws URISyntaxException {
        log.debug("REST request to update ShopDomain : {}", shopDomain);
        if (shopDomain.getId() == null) {
            return create(shopDomain);
        }
        shopDomainRepository.save(shopDomain);
        shopDomainSearchRepository.save(shopDomain);
        return ResponseEntity.ok().build();
    }

    /**
     * GET  /shopDomains -> get all the shopDomains.
     */
    @RequestMapping(value = "/shopDomains",
            method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    @Timed
    public ResponseEntity<List<ShopDomain>> getAll(@RequestParam(value = "page" , required = false) Integer offset,
                                  @RequestParam(value = "per_page", required = false) Integer limit)
        throws URISyntaxException {
        Page<ShopDomain> page = shopDomainRepository.findAll(PaginationUtil.generatePageRequest(offset, limit));
        HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/api/shopDomains", offset, limit);
        return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK);
    }

    /**
     * GET  /shopDomains/:id -> get the "id" shopDomain.
     */
    @RequestMapping(value = "/shopDomains/{id}",
            method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    @Timed
    public ResponseEntity<ShopDomain> get(@PathVariable Long id) {
        log.debug("REST request to get ShopDomain : {}", id);
        return Optional.ofNullable(shopDomainRepository.findOne(id))
            .map(shopDomain -> new ResponseEntity<>(
                shopDomain,
                HttpStatus.OK))
            .orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
    }

    /**
     * DELETE  /shopDomains/:id -> delete the "id" shopDomain.
     */
    @RequestMapping(value = "/shopDomains/{id}",
            method = RequestMethod.DELETE,
            produces = MediaType.APPLICATION_JSON_VALUE)
    @Timed
    public void delete(@PathVariable Long id) {
        log.debug("REST request to delete ShopDomain : {}", id);
        shopDomainRepository.delete(id);
        shopDomainSearchRepository.delete(id);
    }

    /**
     * SEARCH  /_search/shopDomains/:query -> search for the shopDomain corresponding
     * to the query.
     */
    @RequestMapping(value = "/_search/shopDomains/{query}",
        method = RequestMethod.GET,
        produces = MediaType.APPLICATION_JSON_VALUE)
    @Timed
    public List<ShopDomain> search(@PathVariable String query) {
        return StreamSupport
            .stream(shopDomainSearchRepository.search(queryString(query)).spliterator(), false)
            .collect(Collectors.toList());
    }
}
